﻿using AutoCommunication.Base;
using System;
using System.Collections.Generic;

#if NET461_OR_GREATER || NET5_0_OR_GREATER

using System.Windows.Forms;

namespace AutoCommunication.Helper
{
    public static partial class MethodExt
    {
        #region winform

        private static System.Windows.Forms.Timer timer = null;
        private static readonly object ctrDicLock = new object();
        private static readonly object timerlock = new object();

        // private static IDevice dev;
        private static Dictionary<Control, Action> CtrActDic = new Dictionary<Control, Action>();

        private static KeyProperty ctrkey = KeyProperty.AccessibleName;

        /// <summary>
        /// 默认会自动更新AccessibleName属性不为空的控件的Text属性,一些自定义控件的更新需要手动放到updateView委托中
        /// </summary>
        /// <param name="ctr">控件</param>
        /// <param name="updateView">定时执行的方法</param>
        /// <param name="interval">定时时间(单位毫秒):建议100以上吧</param>
        /// <param name="key">指定把key放在了控件的什么属性上,默认AccessibleName</param>
        /// <returns></returns>
        public static Result Auto(this Control ctr, Action updateView = null, int interval = 200, KeyProperty key = KeyProperty.AccessibleName)
        {
            Result result = new Result();
            //todo 还不完善:
            //1.增加功能,为不同的控件设置不同的更新频率
            //2.Interval 的设置是否有Bug
            lock (timerlock)
            {
                if (timer == null)
                {
                    timer = new System.Windows.Forms.Timer();
                    timer.Interval = interval;
                    timer.Tick += Timer_Tick;
                }
                if (timer.Interval != interval)
                {
                    timer.Interval = interval;
                }
                if (timer.Enabled == false)
                {
                    timer.Enabled = true;
                }
            }
            lock (ctrDicLock)
            {
                ctr.Disposed += Ctr_Disposed;
                ctrkey = key;
                if (!CtrActDic.ContainsKey(ctr))
                {
                    CtrActDic.Add(ctr, updateView);
                }
            }
            return result;
        }

        private static void Timer_Tick(object sender, EventArgs e)
        {
            lock (ctrDicLock)
            {
                if (CtrActDic.Count <= 0)
                {
                    timer.Stop();
                }
                foreach (Control item in CtrActDic.Keys)
                {
                    UpdateForWinform(item, ctrkey);
                    CtrActDic[item]?.Invoke();
                }
            }
        }

        private static void Ctr_Disposed(object sender, EventArgs e)
        {
#if DEBUG
            Console.WriteLine(((Control)sender).GetType().Name + "   销毁了");
#endif
            lock (ctrDicLock)
            {
                CtrActDic.Remove((Control)sender);
            }
        }

        /// <summary>
        ///  更新界面:
        /// </summary>
        /// <param name="ctr">要更新的控件 </param>
        /// <param name="key">变量名说存放的属性</param>
        private static void UpdateForWinform(Control ctr, KeyProperty key = KeyProperty.AccessibleName)
        {
            switch (key)
            {
                case KeyProperty.AccessibleName:
                    if (ctr.AccessibleName != null && AutoCommunication.Auto.AllVarable.ContainsKey(ctr.AccessibleName.Norm()))
                    {
                        var test = AutoCommunication.Auto.AllVarable[ctr.AccessibleName.Norm()].Value;
                        ctr.Text = AutoCommunication.Auto.AllVarable[ctr.AccessibleName.Norm()].Value?.ToString();
                    }
                    if (ctr.HasChildren)
                    {
                        foreach (Control cctr in ctr.Controls)
                        {
                            UpdateForWinform(cctr);
                        }
                    }
                    break;

                case KeyProperty.Tag:
                    if (ctr.Tag != null && AutoCommunication.Auto.AllVarable.ContainsKey(ctr.Tag.ToString().Norm()))
                    {
                        ctr.Text = AutoCommunication.Auto.AllVarable[ctr.Tag.ToString().Norm()].Value?.ToString();
                    }
                    if (ctr.HasChildren)
                    {
                        foreach (Control cctr in ctr.Controls)
                        {
                            UpdateForWinform(cctr);
                        }
                    }
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        ///  Show这台设备:设备信息以及所有变量以及测试
        /// </summary>
        /// <param name="dev"></param>
        public static void ShowByWinform(this IDevice dev)
        {
            new Form_ShowDevice(dev).Show();
        }

        /// <summary>
        /// Show所有的设备:设备信息以及所有变量以及测试
        /// </summary>
        /// <param name="dev"></param>
        public static void ShowByWinform(this Dictionary<string, IDevice> dev)
        {
            foreach (var item in dev)
            {
                new Form_ShowDevice(item.Value).Show();
            }
        }

        #endregion winform

        /// <summary>
        /// 方便测试
        /// </summary>
        /// <returns></returns>
        public static Result<T> ShowMessageBox<T>(this Result<T> result)
        {
            string err = "";
            if (result.ErrList.Count > 0)
            {
                // Console.WriteLine("不好意思,发生异常了");
                foreach (var item in result.ErrList)
                {
                    err += item;
                }
                MessageBox.Show($"错误信息 :{err}");
            }
            else
            {
                MessageBox.Show("恭喜你,成功");
            }
            return result;
        }

        /// <summary>
        /// 方便测试时候调试使用
        /// </summary>
        /// <returns></returns>
        public static Result ShowMessageBox(this Result result, string info = "")
        {
            string err = "";
            if (result.ErrList.Count > 0)
            {
                // Console.WriteLine("不好意思,发生异常了");
                foreach (var item in result.ErrList)
                {
                    err += item;
                }
                MessageBox.Show($"错误信息 :{err}");
            }
            else
            {
                MessageBox.Show("恭喜你,成功" + info);
            }
            return result;
        }
    }
}

#endif